Skip to content

Legalize odd-width integers for Metal - #1078

Merged
maleadt merged 1 commit into
mainfrom
tb/odd-width-integers
Nov 5, 2026
Merged

maleadt merged 1 commit into
mainfrom
tb/odd-width-integers

Conversation

@maleadt

@maleadt maleadt commented Nov 5, 2026

Copy link
Copy Markdown
Member

Apple's AGX back-end cannot handle integers wider than a byte whose width is not a power of two (JuliaGPU/Metal.jl#1125). Tested on an M1 with macOS 27:

  • loads of them that are less aligned than the type crash the compiler (i12 through i96 at align 1), and i72 accesses crash at any alignment;
  • naturally-aligned stores are widened to the next power of two and silently overwrite the bytes after the value: store i24 ..., align 4 writes 4 bytes, store i56 ..., align 8 writes 8;
  • arithmetic on i40–i56 values crashes, unless it is a zext that the back-end folds into a naturally-aligned load.

SROA introduces these integers when it splits or widens an aggregate. For example, it copies the padding of {i32, i8} as an i24 (the cause of the Julia 1.10 failures in JuliaGPU/AcceleratedKernels.jl#194), and it assembles a 7-byte alloca in an i56.

This PR adds legalize_odd_width_integers!, which does what SelectionDAG's type legalizer does for other back-ends:

  • It promotes odd-width values to the next power of two and leaves their upper bits undefined.
  • Right shifts, division, remainder, comparisons and extensions clear or sign-fill those upper bits first.
  • It splits loads and stores into power-of-two pieces.
  • Uses it doesn't legalize (calls, returns, ...) get the value truncated back, so they see exactly what they saw before.

The pass runs late in lower_air!, because InstCombine narrows the promoted operations back to odd widths.

Validation: the Metal tests pass on 1.10 and 1.13. A device testset covering loads, stores, copies, extensions and arithmetic for i12 to i96 passes 42/42 on 1.10 and 1.13; without this PR, it has 20 compiler crashes and 6 wrong results. That test goes into a Metal.jl PR once this is released.

@codecov

codecov Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.85492% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.78%. Comparing base (709c4cc) to head (e962900).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/metal.jl 95.85% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1078      +/-   ##
==========================================
- Coverage   92.65%   91.78%   -0.87%     
==========================================
  Files          31       31              
  Lines        7501     7693     +192     
==========================================
+ Hits         6950     7061     +111     
- Misses        551      632      +81     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The AGX back-end cannot handle integers wider than a byte whose width is
not a power of two. Underaligned loads of them and most arithmetic on
them crash the compiler, and naturally-aligned stores are widened to the
next power of two, silently overwriting the bytes after the value. SROA
introduces such integers when it splits or widens an aggregate, e.g. to
copy the padding of `{i32, i8}` as an `i24` (Metal.jl#1125).

Promote these values to the next power of two late in the AIR lowering,
as SelectionDAG's type legalizer does for other back-ends, and split
their loads and stores into power-of-two pieces.
@maleadt
maleadt force-pushed the tb/odd-width-integers branch from be95a1e to e962900 Compare November 5, 2026 11:47
@maleadt
maleadt merged commit 38a5625 into main Nov 5, 2026
33 checks passed
@maleadt
maleadt deleted the tb/odd-width-integers branch November 5, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant